﻿using Newtonsoft.Json;
//using XKPlatform.DataModels;
using XKPlatform.Common;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using XKPlatform.DataModels;

namespace XKPlatform.Common
{
    public class WeixinHelper
    {
        public const string GetCode_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=Appid&redirect_uri=http://Url/views/mobile/login.html&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
        public const string AccessToken_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CorpID&corpsecret=SECRET";
        public const string Userinfo_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";

        public const string Jsapi_Ticket_URL = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN";
        public const string MEDIA_Url = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
        public const string WXLogin_Url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";

        public const string Authorize_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&agentid=AGENTID&state=STATE#wechat_redirect";
        //组织架构，可+部门id
        public const string Dep_URL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=ACCESS_TOKEN&id=ROOT_DEPARTMENT_ID";
        public const string UserListInfoByDep_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD";
        public const string UserListInfoByTag_URL = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?access_token=ACCESS_TOKEN&tagid=TAGID";
        //企业微信userid换取openid
        public const string CovertOpeId_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=ACCESS_TOKEN";
        public const string CovertUserId_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_userid?access_token=ACCESS_TOKEN";

        //企业微信同步tag
        public const string Tag_URL = "https://qyapi.weixin.qq.com/cgi-bin/tag/list?access_token=ACCESS_TOKEN";
        //微信推送消息 post
        public static string PushUrl = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN";
        //微信小程序获取token
        public const string Token_Url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        //企业微信推送消息
        public static string QywxPushUrl = " https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN";
		public static string DownloadUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

        public static string GetAppAgentId(int source)
        {
            var minAppAgentId = MemoryCacheHelper.getDictionaryCache("minAppAgentId");
            if (minAppAgentId.Split(',').Length == 1)
                return minAppAgentId;
            return MemoryCacheHelper.getDictionaryCache("minAppAgentId").Split(',')[source - 1];
        }

        public static string GetAppSecret(int source)
        {
            var minAppSecret = MemoryCacheHelper.getDictionaryCache("minAppSecret");
            if (minAppSecret.Split(',').Length == 1)
                return minAppSecret;
            return MemoryCacheHelper.getDictionaryCache("minAppSecret").Split(',')[source - 1];
        }



        #region 获取企业微信AppToken
        public static void GetAppToken(int source, out string access_token)
        {
            access_token = "";
            try
            {
                var cache_token = SqlHelper.GetSingle("select access_token from SysAccessToken where RecordStatus = 0 and DATEADD(HOUR,2,CreatedOn)>dbo.getLocalDate() and type='qywxAppToken' and source=@source", new SqlParameter("@source", source));

                if (cache_token != null)
                    access_token = cache_token.ToString();

                if (string.IsNullOrEmpty(access_token))
                {
                    string Secret = MemoryCacheHelper.getDictionaryCache("qywxAppSecret").Split(',')[source - 1];
                    string Corpid = MemoryCacheHelper.getDictionaryCache("qywxCorpid").Split(',')[source - 1];

                    var url = AccessToken_URL.Replace("CorpID", Corpid).Replace("SECRET", Secret);

                    var token = new ClientHelper().SendRequestGet<WXResult_Token>(url);
                    if (token != null && token.access_token != null && token.errcode == 0)
                    {
                        access_token = token.access_token;
                        SqlHelper.ExecuteSql("insert into SysAccessToken VALUES('" + token.access_token + "','" + DateTime.Now + "',0," + source + ",'qywxAppToken')");
                    }
                    else
                    {
                        LogHelper.SaveLog("GetToken", "source：" + source + "url：" + url + "errcode：" + token.errcode + "，access_token：" + token.access_token + "，errmsg：" + token.errmsg);
                    }
                }
            }
            catch (Exception ex)
            {
                access_token = "";
                LogHelper.SaveLog(ex);
            }
        }
        
        #endregion

        #region 获取企业微信同步Token
        public static void GetSyncToken(int source,out string access_token)
        {
            access_token = "";
            try
            {
                var cache_token = SqlHelper.GetSingle("select access_token from SysAccessToken where RecordStatus = 0 and DATEADD(HOUR,2,CreatedOn)>dbo.getLocalDate() and type='syncToken' and source=@source",new SqlParameter("@source", source));

                if (cache_token != null)
                    access_token = cache_token.ToString();

                if (string.IsNullOrEmpty(access_token))
                {
                    string Secret = MemoryCacheHelper.getDictionaryCache("qywxSynSecret").Split(',')[source-1];
                    string Corpid = MemoryCacheHelper.getDictionaryCache("qywxSynCorpid").Split(',')[source - 1];

                    var url = AccessToken_URL.Replace("CorpID", Corpid).Replace("SECRET", Secret);

                    var token = new ClientHelper().SendRequestGet<WXResult_Token>(url);
                    if (token != null && token.access_token != null && token.errcode == 0)
                    {
                        access_token = token.access_token;
                        SqlHelper.ExecuteSql("insert into SysAccessToken VALUES('" + token.access_token + "','" + DateTime.Now + "',0,"+source+",'syncToken')");
                    }
                    else
                    {
                        LogHelper.SaveLog("GetToken", "source："+source+"url：" + url + "errcode：" + token.errcode + "，access_token：" + token.access_token + "，errmsg：" + token.errmsg);
                    }
                }
            }
            catch (Exception ex)
            {
                access_token = "";
                LogHelper.SaveLog(ex);
            }
        }
        #endregion

        #region 获取微信APPToken
        //public static void GetWxToken(out string access_token)
        //{
        //    try
        //    {
        //        var cache_token = SqlHelper.GetSingle("select access_token from SysAccessToken where RecordStatus = 0 and DATEADD(HOUR,2,createtime)>dbo.getLocalDate() and type='appToken'");

        //        if (cache_token != null)
        //            access_token = cache_token.ToString();
        //        else
        //        {
        //            var url = Token_Url.Replace("APPID", HttpContextCore.Configuration["Weixin:APPID"])
        //                      .Replace("APPSECRET", HttpContextCore.Configuration["Weixin:SECRET"]);
        //            ClientHelper client = new ClientHelper();
        //            var res = client.SendRequestGet<WXResult_Token>(url);
        //            access_token = res.access_token;
        //            SysAccessToken model = new SysAccessToken();
        //            model.access_token = res.access_token;
        //            model.CreatedOn = DateTime.Now;
        //            model.RecordStatus = false;
        //            model.type = "appToken";
        //            SqlHelper.InsertSql(model);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        access_token = "";
        //        LogHelper.SaveLog(ex);
        //    }
        //}
        #endregion

        #region 签名算法
        /// <summary>
        /// 签名算法     
        /// </summary>
        /// <param name="jsapi_ticket">jsapi_ticket</param>
        /// <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
        /// <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
        /// <param name="url">当前网页的URL，不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
        /// <returns></returns>
        //public static WxAppInfo GetSignature(string noncestr, string timestamp, string url)
        //{
        //    WxAppInfo result = new WxAppInfo();
        //    try
        //    {
        //        int count = 1, errorCount = 5;
        //        do
        //        {
        //            GetAppToken(out string access_token);

        //            if (!string.IsNullOrEmpty(access_token))
        //            {
        //                result.access_token = access_token;

        //                result.ticket = GetJsapiTicket(access_token);

        //                if (!string.IsNullOrEmpty(result.ticket))
        //                {
        //                    //获取当前页面url   
        //                    var string1Builder = new StringBuilder();
        //                    string1Builder.Append("jsapi_ticket=").Append(result.ticket).Append("&")
        //                                  .Append("noncestr=").Append(noncestr).Append("&")
        //                                  .Append("timestamp=").Append(timestamp).Append("&")
        //                                  .Append("url=").Append(url);
        //                    var string1 = string1Builder.ToString();

        //                    result.sign = SHA1(string1, Encoding.UTF8);
        //                }
        //            }
        //            count++;
        //        } while (((result.errcode == 40014 || result.errcode == 42001)) && count <= errorCount);
        //    }
        //    catch (Exception ex)
        //    {
        //        LogHelper.SaveLog(ex);
        //    }

        //    return result;
        //}
        //private static string GetJsapiTicket(string accessToken, bool IsRetrieve = false)
        //{
        //    string ticket = "";
        //    try
        //    {
        //        var cache_ticket = SqlHelper.GetSingle("select access_token from SysAccessToken where RecordStatus = 0 and DATEADD(HOUR,2,createtime)>dbo.getLocalDate() and type='ticket'");

        //        if (cache_ticket != null)
        //            ticket = cache_ticket.ToString();

        //        if (string.IsNullOrEmpty(ticket))
        //        {
        //            string url = Jsapi_Ticket_URL.Replace("ACCESS_TOKEN", accessToken);
        //            var result = new ClientHelper().SendRequestGet<WxAppInfo>(url);
        //            if (result != null && result.ticket != null && result.errcode == 0)
        //            {
        //                ticket = result.ticket;
        //                SqlHelper.ExecuteSql("insert into SysAccessToken VALUES('" + ticket + "','" + DateTime.Now + "',0,'ticket')");
        //            }
        //            else
        //            {
        //                LogHelper.SaveLog("GetJsapiTicket", "url：" + url + "errcode：" + result.errcode + "，access_token：" + result.ticket + "，errmsg：" + result.errmsg);
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LogHelper.SaveLog(ex);
        //    }

        //    return ticket;
        //}

        /// <summary>
        /// SHA1 加密，返回小写字符串
        /// </summary>
        /// <param name="content">需要加密字符串</param>
        /// <param name="encode">指定加密编码</param>
        /// <returns>返回40位大写字符串</returns>
        //private static string SHA1(string content, Encoding encode)
        //{
        //    try
        //    {
        //        SHA1 sha1 = new SHA1CryptoServiceProvider();
        //        byte[] bytes_in = encode.GetBytes(content);
        //        byte[] bytes_out = sha1.ComputeHash(bytes_in);
        //        sha1.Dispose();
        //        string result = BitConverter.ToString(bytes_out);
        //        result = result.Replace("-", "");
        //        result = result.ToLower();
        //        return result;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new Exception("SHA1加密出错：" + ex.Message);
        //    }
        //}
        #endregion

        #region 同步企业微信用户 
        public static bool QywxSync()
        {
            var number = new Random().Next(10000, 99999999);
            try
            {
                var SynCorpid = MemoryCacheHelper.getDictionaryCache("qywxSynCorpid").Split(',');

                var defaultPassword = MemoryCacheHelper.getDictionaryCache("SysDefaultPassword");

                for (int i = 0; i < SynCorpid.Length; i++)
                {

                    DataTable dt = JsonHelper.CreateTable(typeof(SysDepartment));
                    DataTable userdt = JsonHelper.CreateTable(typeof(SysUser));

                    var source = i + 1;
                    GetSyncToken(source, out string access_token);

                    if (string.IsNullOrEmpty(access_token))
                        continue;


                    if (source == 1)
                    {
                        var ROOT_DEPARTMENT = MemoryCacheHelper.getDictionaryCache("qywxSynDepartmentIds").Split('|')[i].Split(',');

                        foreach (var item in ROOT_DEPARTMENT)
                        {
                            var ROOT_DEPARTMENT_ID = item;

                            var url = Dep_URL.Replace("ACCESS_TOKEN", access_token).Replace("ROOT_DEPARTMENT_ID", ROOT_DEPARTMENT_ID);

                            var departmentSync = new ClientHelper().SendRequestGet<DepartmentSync>(url);

                            if (departmentSync.errcode == 0)
                            {
                                foreach (var department in departmentSync.Department)
                                {
                                    DataRow dr = dt.NewRow();
                                    dr["Source"] = source;
                                    dr["RecordStatus"] = false;
                                    dr["DepartmentID"] = Guid.NewGuid();
                                    dr["ImportBatch"] = number;
                                    dr["DepartmentNo"] = department.id;
                                    dr["DepartmentName"] = department.name;
                                    dr["ParentNo"] = department.parentid;
                                    dr["OrderNo"] = department.order;
                                    dr["CreatedBy"] = "System";
                                    dr["CreatedOn"] = DateTime.Now;

                                    dr["Org"] = "HFC";

                                    dt.Rows.Add(dr);
                                }
                            }

                            url = UserListInfoByDep_URL.Replace("ACCESS_TOKEN", access_token).Replace("DEPARTMENT_ID", ROOT_DEPARTMENT_ID).Replace("FETCH_CHILD", "1");
                            var userSync = new ClientHelper().HttpGetAsyncByProxy<UserSync>(url);

                            if (userSync.errcode == 0)
                            {
                                foreach (var user in userSync.UserList)
                                {
                                    DataRow dr = userdt.NewRow();
                                    dr["UserID"] = Guid.NewGuid();
                                    dr["ImportBatch"] = number;
                                    dr["RecordStatus"] = false;
                                    dr["Source"] = source;
                                    dr["UserNo"] = user.userid;
                                    dr["QywxUserId"] = user.userid;
                                    dr["UserName"] = user.name;
                                    dr["DepartmentNo"] = user.department[0];
                                    dr["PostNo"] = user.position;
                                    dr["Mobile"] = user.mobile;
                                    dr["Email"] = user.email;
                                    dr["CorpName"] = "HFC";

                                    dr["OrderNo"] = user.order[0];

                                    dr["CreatedBy"] = "System";
                                    dr["CreatedOn"] = DateTime.Now;
                                    //dr["ChangePasswordTime"] = DateTime.Now;
                                    dr["Password"] = defaultPassword;
                                    dr["Org"] = "HFC";
                                    //dr["Password"] = EncryptHelper.MD5(GetrandomPassWord());
                                    userdt.Rows.Add(dr);
                                }
                            }
                        }

                        SqlHelper.BatchInsert(dt, "SysDepartment");

                       SqlHelper.ExecuteSql(@"
--部门处理
delete SysDepartment where Source is null or RecordStatus<>0  or ImportBatch not in (0,@ImportBatch)

--删除本次同步不存在的部门
delete a from SysDepartment a where a.Source=@Source and a.ImportBatch=0 
and not exists (select 1 from SysDepartment where a.DepartmentNo=DepartmentNo and ImportBatch=@ImportBatch and Source=@Source)  

--更新本次同步部门
update a set a.ModifiedOn=@ModifiedOn,a.ModifiedBy='System',a.OrderNo=b.OrderNo,a.Org=b.Org,
a.DepartmentName=b.DepartmentName,a.ParentNo=b.ParentNo
from SysDepartment a join SysDepartment b on a.DepartmentNo=b.DepartmentNo 
and b.Source=@Source and b.ImportBatch=@ImportBatch 
and a.Source=@Source and a.ImportBatch=0

--删除本次导入已经更新了的部门
delete b from SysDepartment a,SysDepartment b where a.DepartmentNo=b.DepartmentNo and a.ImportBatch=0 and b.ImportBatch=@ImportBatch and a.Source=@Source and b.Source=@Source

--本次同步新增的部门
update a set a.ImportBatch=0 from SysDepartment a where a.ImportBatch=@ImportBatch and a.Source=@Source 

--parentid 处理
update a set a.ParentID=b.DepartmentID from SysDepartment a ,SysDepartment b where a.ParentNo=b.DepartmentNo and a.RecordStatus=0 and b.RecordStatus=0 and a.Source=@Source and b.Source=@Source

", new SqlParameter[] { new SqlParameter("@ImportBatch", number), new SqlParameter("@ModifiedOn", DateTime.Now), new SqlParameter("@Source", source) });
                    }
                    if (source == 2)
                    {
                        var url = UserListInfoByDep_URL.Replace("ACCESS_TOKEN", access_token).Replace("DEPARTMENT_ID", "1").Replace("FETCH_CHILD", "1");
                      var userSync = new ClientHelper().HttpGetAsyncByProxy<UserSync>(url);

                        if (userSync.errcode == 0)
                        {
                            foreach (var user in userSync.UserList)
                            {
                                DataRow dr = userdt.NewRow();
                                
                                dr["UserID"] = Guid.NewGuid();
                                dr["ImportBatch"] = number;
                                dr["RecordStatus"] = false;
                                dr["Source"] = source;
                                dr["UserNo"] = user.userid;
                                dr["QywxUserId"] = user.userid;
                                dr["UserName"] = user.name;
                                dr["DepartmentNo"] = "000000";
                                dr["PostNo"] = user.position;
                                dr["Mobile"] = user.mobile;
                                dr["Email"] = user.email;

                                dr["CorpName"] = "000000";

                                if (user.extattr != null && user.extattr.attrs != null && user.extattr.attrs.Count > 0)
                                {
                                    foreach (var attr in user.extattr.attrs)
                                    {
                                        if (attr.name == "公司"&&!string.IsNullOrEmpty(attr.value))
                                        {
                                            var company = attr.value.EndsWith(".") ? attr.value.Substring(0, attr.value.Length - 1) : attr.value;
                                            dr["DepartmentNo"] = company;
                                            dr["CorpName"] = company;
                                            break;
                                        }
                                    }
                                }

                                dr["OrderNo"] = user.order[0];
                                dr["CreatedBy"] = "System";
                                dr["CreatedOn"] = DateTime.Now;
                                //dr["ChangePasswordTime"] = DateTime.Now;
                                dr["Password"] = defaultPassword;

                                //dr["Password"] = EncryptHelper.MD5(GetrandomPassWord());
                                userdt.Rows.Add(dr);
                            }
                        }
                    }

                    if (userdt.Rows.Count == 0)
                        continue;
                    
                    SqlHelper.BatchInsert(userdt, "SysUser");

                    SqlHelper.ExecuteSql(@"
--用户处理
delete SysUser where Source is null or RecordStatus<>0  or ImportBatch not in (0,@ImportBatch)

--修改本次同步用户岗位
/*update a set a.PostNo=null from SysUser a where a.ImportBatch=@ImportBatch and a.Source=@Source 
and a.PostNo not in (select PostName from SysPost where RecordStatus=0)

update a set a.PostNo=(select top 1 PostNo from SysPost where RecordStatus=0 and PostName=a.PostNo) from SysUser a 
where a.ImportBatch=@ImportBatch and a.Source=@Source*/

--删除本次同步不存在的用户
delete a from SysUser a where a.Source=@Source and a.ImportBatch=0 
and not exists (select 1 from SysUser where a.UserNo=UserNo and ImportBatch=@ImportBatch and Source=@Source)  


--更新本次同步用户
update a set a.ModifiedOn=@ModifiedOn,a.ModifiedBy='System',a.RecordStatus=0,a.CorpName=b.CorpName,a.Org=b.Org,
a.UserName=b.UserName,a.Mobile=b.Mobile,a.Email=b.Email,a.QywxUserId=b.QywxUserId,a.DepartmentNo=b.DepartmentNo
from SysUser a join SysUser b on a.UserNo=b.UserNo 
and b.Source=@Source and b.ImportBatch=@ImportBatch 
and a.Source=@Source and a.ImportBatch=0

--删除本次导入已经更新了的用户
delete b from SysUser a,SysUser b where a.UserNo=b.UserNo and a.ImportBatch=0 and b.ImportBatch=@ImportBatch and a.Source=@Source and b.Source=@Source

--公司作为部门
delete a from SysDepartment a where a.Source=2 and not EXISTS (select 1 from SysUser where a.DepartmentNo=DepartmentNo and source=2)
insert into SysDepartment (DepartmentID,DepartmentNo,DepartmentName,CreatedOn,CreatedBy,RecordStatus,ImportBatch,Source)
select newid(),CorpName,CorpName,@ModifiedOn,'System',0,0,2 from (
select DISTINCT CorpName from SysUser where Source=2 and isnull(CorpName,'')<>'' group by CorpName
) t where not EXISTS(select 1 from SysDepartment where t.CorpName=DepartmentNo)


--本次导入新增的用户
update a set a.ImportBatch=0 from SysUser a where a.ImportBatch=@ImportBatch and a.Source=@Source

delete a from SysUser a, (
select row_number() over(partition by UserNo order by CreatedOn) rown,UserNo,UserID from SysUser
) t where t.rown>1 and a.UserID=t.UserID

--更新部门ID
update a set a.Org=b.OrgNo,a.DepartmentNo=b.OrgNo from SysUser a,SysOrgUser b where a.Email=b.Email and isnull(a.Org,'')!=b.OrgNo
update a set a.DepartmentID=b.DepartmentID from SysUser a,SysDepartment b where a.DepartmentNo=b.DepartmentNo

update b set b.Org = a.OrgNo from SysOrg a,SysDepartment b where a.DepartmentNo = b.DepartmentNo and a.OrgNo is not null and a.RecordStatus = 0
update b set b.Org = a.Org from SysDepartment a,SysUser b where a.DepartmentID = b.DepartmentID and a.Org is not null and a.RecordStatus = 0

--删除部门不存在了的用户
delete a from SysUser a where not EXISTS (select 1 from SysDepartment where a.DepartmentID=DepartmentID)
delete a from SysPostRole a where not EXISTS (select 1 from SysUser where UserNo=a.UserNo) and UserNo is not null
delete a from SysPostUserRelevance a where not EXISTS (select 1 from SysUser where UserNo=a.UserNo and a.Org=Org)
delete a from tblTaskUser a where not EXISTS (select 1 from SysUser where UserNo=a.UserNo and a.Org=Org)

", new SqlParameter[] { new SqlParameter("@ImportBatch", number), new SqlParameter("@ModifiedOn", DateTime.Now), new SqlParameter("@Source", source) });

                }
                return true;
            }
            catch (Exception ex)
            {
                SqlHelper.ExecuteSql("delete SysDepartment where ImportBatch=@ImportBatch", new SqlParameter("@ImportBatch", number));
                SqlHelper.ExecuteSql("delete SysUser where ImportBatch=@ImportBatch", new SqlParameter("@ImportBatch", number));
                LogHelper.SaveLog(ex);
                return false;
            }
        }
        #endregion

        #region 同步openid
        public static bool OpenidSync()
        {
            try
            {
                var SynCorpid = MemoryCacheHelper.getDictionaryCache("qywxSynCorpid").Split(',');
                for (int i = 0; i < SynCorpid.Length; i++)
                {
                    var source = i + 1;
                    GetSyncToken(source, out string access_token);
                    if (string.IsNullOrEmpty(access_token))
                        continue;

                    QuerySuite querySuite = new QuerySuite("SysUser where isnull(QywxUserId,'')!='' and isnull(Openid,'')=''", "UserID,QywxUserId");
                    querySuite.AddParam("Source", "=", source);

                    List<SysUser> models = ModelHelper<SysUser>.ConvertToModelList(SqlHelper.Query(querySuite.SelectSql, querySuite.Params).Tables[0]);
                    var errCount = 0;
                    foreach (var model in models)
                    {
                        if (errCount > 10)
                            break;

                        OpenidResult result = new OpenidResult();
                        var url = CovertOpeId_URL.Replace("ACCESS_TOKEN", access_token);
                        string param = "{\"userid\":\"" + model.QywxUserId + "\"}";
                        result = new ClientHelper().HttpPostAsync<OpenidResult>(url, param);

                        if (result.errcode == 0 && result.openid != null)
                            SqlHelper.ExecuteSql(@"update SysUser set openid=@openid where UserID=@userid",
                                new SqlParameter[] {
                                    new SqlParameter("@openid", result.openid),
                                    new SqlParameter("@userid", model.UserID)
                                });
                        else if (result.errcode != 43004)
                            errCount++;
                    }
                }
                return true;
            }
            catch (Exception ex)
            { 
                LogHelper.SaveLog(ex);
                return false;
            }
        }
        #endregion

        #region openid userid 互换
        public static string GetUserIdFromOpenid(string opneid)
        {
            var synCorpid = MemoryCacheHelper.getDictionaryCache("qywxSynCorpid").Split(',')[1];
            GetSyncToken(2, out string access_token);
            if (string.IsNullOrEmpty(access_token))
                return "";

            var url = CovertUserId_URL.Replace("ACCESS_TOKEN", access_token);
            string param = "{\"openid\":\"" + opneid + "\"}";
            var result = new ClientHelper().HttpPostAsync<UseridResult>(url, param);

            if (result.errcode == 0)
                return result.userid;
            else return "";
        }

        public static string GetOpenidFromUserId(string userId)
        {
            var synCorpid = MemoryCacheHelper.getDictionaryCache("qywxSynCorpid").Split(',')[1];
            GetSyncToken(2, out string access_token);
            if (string.IsNullOrEmpty(access_token))
                return "";

            var url = CovertOpeId_URL.Replace("ACCESS_TOKEN", access_token);
            string param = "{\"userid\":\"" + userId + "\"}";
            var result = new ClientHelper().HttpPostAsync<OpenidResult>(url, param);

            if (result.errcode == 0)
                return result.openid;
            else return "";
        }
        #endregion

        #region 通知推送
        public static void PushMsg(string touser, MiniprogramNotice notic,int Source)
        {
            //企业微信推送
            GetAppToken(Source, out string token);
            string url = QywxPushUrl.Replace("ACCESS_TOKEN", token);

            foreach (var item in notic.content_item)
            {
                if (item.value.Length > 30)
                    item.value = item.value.Substring(0, 30);
            }

            CorpSendText corpSendText = new CorpSendText()
            {
                touser = touser,
                msgtype = "miniprogram_notice",
                miniprogram_notice = notic
            };

            var res = new ClientHelper().HttpPostAsync(url, JsonConvert.SerializeObject(corpSendText));

        }
        public static void PushMiniprogramMsgTest(string touser)
        {
            //企业微信推送
            GetAppToken(1, out string token);
            string url = QywxPushUrl.Replace("ACCESS_TOKEN", token);

            var appid = WeixinHelper.GetAppAgentId(1);// MemoryCacheHelper.getDictionaryCache("minAppAgentId");

            List<NoticeContentItem> contentItem = new List<NoticeContentItem>();
            contentItem.Add(
                new NoticeContentItem()
                {
                    key = "会议室",
                    value = "402"
                }
            );
            MiniprogramNotice notic = new MiniprogramNotice()
            {
                appid = appid,
                page = "/pages/XKPlatform/statistics/StopReport",
                title ="测试测试",
                description=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                emphasis_first_item=false,
                content_item=contentItem
            };

            CorpSendText corpSendText = new CorpSendText()
            {
                touser = touser,
                msgtype = "miniprogram_notice",
                miniprogram_notice = notic
            };

            var res = new ClientHelper().HttpPostAsync(url, JsonConvert.SerializeObject(corpSendText));
        }
        #endregion

        #region 生成随机密码
        //public static string GetrandomPassWord()
        //{
        //    string[] lettr = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
        //    string[] specialChar = new[] { "!", "@", "*", "_" };
        //    List<string> password = new List<string>();
        //    try
        //    {
        //        Random randmo = new Random();
        //        for (int i = 0; i < 3; i++)
        //        {
        //            int lettrIndex = randmo.Next(0, 25);
        //            int newrandom = randmo.Next(1, 100);
        //            if ((newrandom % 2) == 0)
        //            {
        //                password.Add(lettr[lettrIndex]);
        //            }
        //            else
        //            {
        //                password.Add(lettr[lettrIndex].ToUpper());
        //            }
        //            int specialCharIndex = randmo.Next(0, 3);
        //            password.Add(specialChar[specialCharIndex]);
        //            int randomNum = randmo.Next(0, 9);
        //            password.Add(randomNum.ToString());

        //        }
        //        password.Add(lettr[randmo.Next(1, 25)]);
        //        string newPassWord = "";
        //        password.ForEach(m => newPassWord += m);
        //        return newPassWord;
        //    }
        //    catch (Exception)
        //    {
        //        return "Nestle@defult123";
        //    }
        //}
        #endregion  
    }
}
